//	Copyright (C) 2007 Christian Martick, http://juhu-mac.blogspot.com
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.


#import "mobileJuhuApp.h"

@implementation mobileJuhuApp

#pragma mark Helpers

- (void) _checkDefaults
{
	// check and clean defaults
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	
	if ([defaults objectForKey: @"text"] == nil)
		[defaults setObject: @"" forKey: @"text"];
	if ([defaults objectForKey: @"location"] == nil)
		[defaults setObject: @"" forKey: @"location"];
	if ([defaults objectForKey: @"stream"] == nil)
		[defaults setObject: @"public" forKey: @"stream"];
	if ([defaults objectForKey: @"username"] == nil)
		[defaults setObject: @"" forKey: @"username"];
	if ([defaults objectForKey: @"personalkey"] == nil)
		[defaults setObject: @"" forKey: @"personalkey"];

	// stream selector
	if ((![[defaults stringForKey: @"stream"] isEqualToString: @"private"])
		&& (![[defaults stringForKey: @"stream"] isEqualToString: @"public"]))
		[defaults setObject: @"public" forKey: @"stream"];

}

- (void) _timerSetup
{
	if ([[[NSUserDefaults standardUserDefaults] objectForKey: @"autoupdate"] boolValue])
	{
		[theTimer invalidate];
		theTimer = [NSTimer scheduledTimerWithTimeInterval: 10*60
			target: self selector: @selector ( update:)  userInfo: nil repeats: YES];
	} else
	{
		[theTimer invalidate];
		theTimer = nil;
	}
}

#pragma mark UIApplication

- (void) dealloc
{
	[theTimer invalidate];
	[jaiku release];
	[mainView release];
	[settingsView release];
	[overView release];
	[readView release];
	[window release];
	[super dealloc];
}

- (void) applicationDidFinishLaunching: (id) unused
{	
	[self setStatusBarMode: 1 duration: 0.1];
	[self _checkDefaults];
	
	// the api object
	jaiku = [[smcJaikuAPI alloc] initWithUsername: [[NSUserDefaults standardUserDefaults] stringForKey: @"username"]
		andPersonalKey: [[NSUserDefaults standardUserDefaults] stringForKey: @"personalkey"]];
	[jaiku setDelegate: self];

	// setup timer for autoupdate
	theTimer = nil;
	[self _timerSetup];
	
	// set up window
	struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
	window = [[UIWindow alloc] initWithContentRect: rect];
	
	// settings view setup
	rect.origin = CGPointMake(0.0f, 0.0f);
	settingsView = [[smcSettingsView alloc] initWithFrame: rect];
	[settingsView setDelegate: self];
	
	// main view setup
	rect.origin = CGPointMake(0.0f, 0.0f);
	mainView = [[smcMainView alloc] initWithFrame: rect];
	[mainView setDelegate: self];

	// over view setup
	overView = [[smcOverview alloc] initWithFrame: rect andDelegate: self];
	[overView setJaikuObject: jaiku];
	
	// read view setup
	readView = [[smcReadView alloc] initWithFrame: rect];
	[readView setDelegate: self];
	[readView setJaikuObject: jaiku];
	
	// set content and add view
	[window setContentView: [[UITransitionView alloc] initWithFrame: rect]];
	[[window contentView] addSubview: overView];

	// get last text
	[mainView setText: [[NSUserDefaults standardUserDefaults] stringForKey: @"text"]];
	[mainView setLocation: [[NSUserDefaults standardUserDefaults] stringForKey: @"location"]];
	
	[mainView setIsCommentView: NO];
	
    [window orderFront: self];
    [window makeKey: self];
    [window _setHidden: NO];    
	
	// update
	_hud = [[UIProgressHUD alloc] initWithWindow: window];
	[_hud setText: @"Please wait..."];
	[_hud show: YES];
	[self update: self];	
}

- (void)applicationWillSuspend
{
	//no need for badge
	[self removeApplicationBadge];	
	
	[mainView shouldHideKeyboardForView: nil];
}

- (void)applicationSuspend:(struct __GSEvent *)fp8
{
	// do something, or not...
	// super terminates, this doesn't...	
}

- (void)applicationDidResume
{
	[super applicationDidResume];
	[self setStatusBarMode: 1 duration: 0.1];

	// update
	[self update: self];
}

#pragma mark Some actions

- (id) deleteSomething: (id) url
{
	// show progress
	[self setStatusBarShowsProgress: YES];

	// try to delete the post, returns nil or error
	id error = [jaiku deletePostOrCommentWithURL: url];	
	
	// stop progress
	[self setStatusBarShowsProgress: NO];
	
	return error;
}

- (id) sendSomething: (id) info
{
	// show progress
	[self setStatusBarShowsProgress: YES];
	
	NSError *error = nil;
	
	if ([[info objectForKey: @"comment"] boolValue])
	{
		// just a comment
		error = [jaiku postComment: [info objectForKey: @"text"] to: [info objectForKey: @"URL"]];
		[self setStatusBarShowsProgress: NO];		
	} else
	{
		// normal post, do it...
		error = [jaiku postMessage: [info objectForKey: @"text"]
			withLocation: [info objectForKey: @"location"] 
			andIcon: [[info objectForKey: @"icon"] intValue] 
			generated: NO];
	}
	
	// any problems?
	if (error == nil)
		[mainView resetView]; // clear icon and text, but not location
	else
	{
		// show error message
		UIAlertSheet *alertSheet = [[[UIAlertSheet alloc] initWithTitle: @"Could not send"
			buttons: nil
			defaultButtonIndex: 0 
			delegate: nil
			context: nil] autorelease];
		[alertSheet setBodyText: [[error userInfo] objectForKey: @"errorText"]];
		[alertSheet popupAlertAnimated: YES];
	}
	
	[self setStatusBarShowsProgress: NO];
}

- (void) update: (id) sender
{
	// update jaiku
	[self setStatusBarShowsProgress: YES];
	
	// show hud if no posts
	if ([[jaiku stream: [[NSUserDefaults standardUserDefaults] stringForKey: @"stream"]] count]  == 0)
	{
		if (_hud == nil)
		{
			_hud = [[UIProgressHUD alloc] initWithWindow: window];
			[_hud setText: @"Please wait..."];
			
		}
		[_hud show: YES];
	}
	
	// do update(s)
	[jaiku updateFriendListSynchronously: NO];
	[jaiku beginUpdateForStream: [[NSUserDefaults standardUserDefaults] stringForKey: @"stream"]];
}

#pragma mark Jaiku API delegate
- (void) stream: (NSString*) stream updatedWithResult: (id) result andIndexSetForNewPosts: (id) indexSet
{
	// progress things should stop
	[self setStatusBarShowsProgress: NO];
	[_hud show: NO];
	[_hud release];
	_hud = nil;
	
	[overView reload];
	
	// new ones: set badge, play sound, scroll to top...
	if ([indexSet count] != 0)
	{
		[self setApplicationBadge: [NSString stringWithFormat: @"%i", [indexSet count]]];
		
		if ([[NSUserDefaults standardUserDefaults] boolForKey: @"playsound"])
			[smcAudioPlayback playApplicationSoundNamed: @"ping"];
		[overView showTop];
	}
}

- (void) streamUpdateFailedWithError: (NSError *) error
{
	// stop progress
	[self setStatusBarShowsProgress: NO];
	[_hud show: NO];
	[_hud release];
	_hud = nil;
	
	// error message or not? mh.
	if ((![self isSuspended]) && ([error code] == -1003)) // operation could not be completed - credentials...
	{
		UIAlertSheet *alertSheet = [[[UIAlertSheet alloc] initWithTitle: @"Could not catch stream"
			buttons: nil
			defaultButtonIndex: 0 
			delegate: nil
			context: nil] autorelease];
		[alertSheet setBodyText: @"Maybe your account credentials are wrong."];
		[alertSheet popupAlertAnimated: YES];
	}
	NSLog(@"fail: %@", error);	
}

#pragma mark view switch / animation delegate

- (void) animateFromTo: (NSArray *) sender
{
	// expecting sender to be array with view an integer
	// 0 - overview, 1 - mainview, 2 - settings, 3 - readview 
	int transitionType = 0;
	id target = nil;
	if ([sender objectAtIndex: 0] == overView)
	{
		switch ([[sender objectAtIndex: 1] intValue])
		{
			case 1: // to main view
				transitionType = 2;
				target = mainView;
				[mainView setIsCommentView: NO];
				break;
			case 2: // settings
				transitionType = 8;
				target = settingsView;
				break;
			case 3: // read view
				[readView setContent: 
					[[jaiku stream: [[NSUserDefaults standardUserDefaults] stringForKey: @"stream"]] objectAtIndex: 
						[overView selected]]];
				transitionType = 1;
				target = readView;			
				break;
		}
	} else if ([sender objectAtIndex: 0] == mainView)
	{
		switch ([[sender objectAtIndex: 1] intValue])
		{
			case 0: // to overview
				transitionType = 1;
				target = overView;
				break;
			case 3: // to read
				transitionType = 9;
				target = readView;			
				break;
		}
	} else if ([sender objectAtIndex: 0] == settingsView)
	{
		// only to over view
		transitionType = 9;
		target = overView;
		
		// maybe autoupdate changed
		[self _timerSetup];
		
		// and what about the username and key?
		[jaiku setUsername: [[NSUserDefaults standardUserDefaults] stringForKey: @"username"]];
		[jaiku setPersonalKey: [[NSUserDefaults standardUserDefaults] stringForKey: @"personalkey"]];
		
		// and update
		[self update: self];
		
	} else if ([sender objectAtIndex: 0] == readView)
	{
		switch ([[sender objectAtIndex: 1] intValue])
		{
			case 0: // to overview
				transitionType = 2;
				target = overView;
				[overView unselect];				
				break;
			case 1: // post a comment, so
				transitionType = 8;
				target = mainView;
								
				// setup mainView
				[mainView setContentForComment: [sender objectAtIndex: 2]];
				[mainView setIsCommentView: YES];
				
				break;
		}
	}

	[[window contentView] transition: transitionType
		fromView: [sender objectAtIndex: 0]
		toView: target];
}
 
#pragma mark alert sheet delegate

- (void) alertSheet: (UIAlertSheet*) sheet buttonClicked: (int) button
{
	[sheet dismiss];
}

@end
